package com.itcast.service.impl;

import com.alibaba.dubbo.config.annotation.Service;
import com.github.pagehelper.Page;
import com.itcast.dao.MenuDao;
import com.itcast.dao.PermissionDao;
import com.itcast.dao.RoleDao;
import com.itcast.dao.UserDao;
import com.itcast.entity.PageResult;
import com.itcast.entity.QueryPageBean;
import com.itcast.entity.Result;
import com.itcast.pojo.Menu;
import com.itcast.pojo.Permission;
import com.itcast.pojo.Role;
import com.itcast.pojo.User;
import com.itcast.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.RequestBody;

import java.util.*;

@Service(interfaceClass = UserService.class)
@Transactional
public class UserServiceImpl implements UserService {
    @Autowired
    private UserDao userDao;

    @Autowired
    private RoleDao roleDao;

    @Autowired
    private PermissionDao permissionDao;

    @Autowired
    private MenuDao menuDao;


    @Autowired
    private BCryptPasswordEncoder bCryptPasswordEncoder;

    /**
     * 查询用户及对应的角色与权限
     * @param username 用户名
     * @return 用户对象
     */
    @Override
    public User findByUserame(String username) {
        User user = userDao.findByUserame(username);
        if (user!=null) {
            Set<Role> roles = roleDao.findByUserId(user.getId());
            if (roles != null) {
                for (Role role : roles) {
                    Set<Permission> permissions = permissionDao.findByRoleId(role.getId());
                    if (permissions != null && permissions.size() > 0) {
                        role.setPermissions(permissions);
                    }
                }
            }
            user.setRoles(roles);
        }
        return user;
    }

    /**
     * 查询用户所能访问的页面
     * @param username
     * @return
     */
    @Override
    public List<Map<String, Object>> getMenu(String username) {
        username=username.trim();
        List<Map<String,Object>> data = new ArrayList<>();

        if (username!=null&&username.length()>0){
            User user = this.findByUserame(username);
            if (user!=null){
                Set<Role> roles = user.getRoles();
                List<Menu> menuList = getMenuList(roles);

                //对菜单页面优先级排序
               Collections.sort(menuList, ( o1, o2)->  o1.getPriority()-o2.getPriority() );
                if (menuList!=null&&menuList.size()>0){
                    for (Menu menu : menuList) {
                        Map<String,Object> map = new HashMap<>();
                        map.put("path",menu.getPath());
                        map.put("title",menu.getName());
                        map.put("icon",menu.getIcon());
                        List<Map<String, Object>> children = getChildren(menu);
                        map.put("children",children);
                        data.add(map);

                    }
                }
            }
        }
        return data;
    }

    /**
     * 获取子菜单数据
     * @param menu
     * @return
     */
    private List<Map<String,Object>> getChildren(Menu menu){
        List<Map<String,Object>> children = new ArrayList<>();
        for (Menu child : menu.getChildren()) {
            Map<String,Object> childrenmap = new HashMap<>();
            childrenmap.put("path",child.getPath());
            childrenmap.put("title",child.getName());
            childrenmap.put("linkUrl",child.getLinkUrl());
            childrenmap.put("children",child.getChildren());
            children.add(childrenmap);
        }
        return children;
    }

    /**
     * 获取菜单数据
     * @param roles
     * @return
     */
    private List<Menu> getMenuList(Set<Role> roles){
        List<Menu> menuList = new ArrayList<>();
        if (roles!=null&&roles.size()>0){
            for (Role role : roles) {
                Set<Menu> menuSet = menuDao.findMenuIdByRoleId(role.getId());
                if (menuSet!=null&& menuSet.size()>0){
                    for (Menu menu : menuSet) {
                        Integer parentMenuId = menu.getParentMenuId();
                        if (parentMenuId==null){
                            menuList.add(menu);
//                                    menuSet.remove(menu);  不可以同时进行增加或删除操作
                        }
                    }
                    menuList = setChilren(menuList,menuSet);
                }
            }
        }
        return menuList;
    }

    /**
     * 为每个菜单设置子菜单并排序
     * @param menuList
     * @param menuSet
     * @return
     */
    private List<Menu> setChilren (List<Menu> menuList,Set<Menu> menuSet){
        for (Menu menu : menuList) {
            List<Menu> menus = new ArrayList<>();
            for (Menu menuChildren : menuSet) {
                if (menuChildren.getParentMenuId()!=null&&menuChildren.getParentMenuId()==menu.getId()){
                    menus.add(menuChildren);
                }
                Collections.sort(menus, ( o1, o2)->  o1.getPriority()-o2.getPriority() );
                menu.setChildren(menus);
            }
        }
        return menuList;
    }

    /**
     * 分页查询
     * @param map
     * @return
     */
    @Override
    public PageResult findPage(Map map) {
        Integer currentPage = (Integer) map.get("currentPage");
        Integer pageSize = (Integer) map.get("pageSize");
        String queryString = (String) map.get("queryString");
        if (queryString!=null){
            queryString = queryString.trim();
            if (queryString.length()>0&&!"null".equalsIgnoreCase(queryString)){
                queryString = "%"+queryString+"%";
            }else {
                queryString=null;
            }
        }
        Page<User> users = userDao.findPage(queryString);
        long total = users.getTotal();
        PageResult pageResult = new PageResult(total,users);

        return pageResult;
    }

    /**
     * 新增用户
     * @param user
     * @return
     */
    @Override
    public Result add( User user,Integer[] roleIds) {
        User u = userDao.findByUserame(user.getUsername());
        if (u!=null){
            return new Result(false,"用户已存在，请重新添加");
        }
        user.setPassword(bCryptPasswordEncoder.encode(user.getPassword()));
        userDao.add(user);
        Integer userId = user.getId();
        if (roleIds!=null){
            for (Integer roleId : roleIds) {
                roleDao.addUserIdAndRoleId(userId,roleId);
            }
        }

        return new Result(true,"用户添加成功");
    }

    /**
     * 编辑回显用户数据
     * @param userId
     * @return
     */
    @Override
    public User findUserById(int userId) {
       return userDao.findById(userId);

    }

    /**
     * 修改用户信息
     * @param user
     * @param roleIds
     */
    @Override
    public void edit(User user, Integer... roleIds) {
        if (user!=null) {
            Integer userId = user.getId();
            userDao.edit(user);
            if (userId != null) {
                if (roleIds != null && roleIds.length > 0) {
                    roleDao.delUserAndRoleByUserId(userId);
                    for (Integer roleId : roleIds) {
                        roleDao.addUserIdAndRoleId(userId, roleId);
                    }
                }
            }
        }

    }

    @Override
    public void delUser(int id) {
        roleDao.delUserAndRoleByUserId(id);
        userDao.delUser(id);
    }

    @Override
    public void delAllUser( List<User> list) {
        if (list!=null && list.size()>0){
            for (User user : list) {
                delUser(user.getId());
            }
        }    }
}
